<?php

use \Smarty;

// BLOCKS

function smarty_pmvc_hasRoles($params, $content, &$smarty, &$repeat) {

	// get the request object
    $request = $smarty->get_registered_object("Request");

    // get the roles
    $roles = $params["roles"];
    if (!is_array($roles)) {
    	$roles = explode(",", $roles);
    }

    // get the user
    $user = pmvc\mvc\security\SecurityUtil::getCurrentUser($request);
    if ($user==NULL) {
    	return "";
    }

    // check the roles
    $userRoles = array_intersect($user->getRoles(), $roles);
    if (count($userRoles)==count($roles)) {
    	return $content;
    }
}

// FUNCTIONS

function smarty_pmvc_getAttrs(array $params, Smarty &$smarty) {
   
	// get the form errors
	$errors = array_key_exists("errors", $params)
		? $params["errors"] 
		: $smarty->get_template_vars("formErrors");

	// check for errors
	$field = (array_key_exists("name", $params)) ? $params["name"] : NULL;
	$hasError = isset($field)
		&& isset($errors)
		&& array_key_exists("fieldErrors", $errors)
		&& array_key_exists($field, $errors["fieldErrors"])
		&& count($errors["fieldErrors"])>=0;

	// add error class
	if ($hasError && array_key_exists("errorClass", $params)) {
		$params["class"] = array_key_exists("class", $params) ? $params["class"]." " : "";
		$params["class"] .= $params["errorClass"];
	}
	unset($params["errorClass"]);

	// build attribute html
	$ret = '';
    foreach ($params as $key => $value) {
    	if (pmvc\util\StringUtil::startsWith($key, "data_", TRUE)) {
    		$key = "data-".substr($key, 5);
    	}
    	$ret .= ' '.$key.'="'.htmlspecialchars($value).'"';
    }   

    // return it
    return $ret;
}

function smarty_pmvc_getSelectedOptions(array $params, Smarty &$smarty) {

	// get the request object
    $request = $smarty->get_registered_object("Request");

	// check for "selectedOptions" first
	$selectedOptions = (isset($params["selectedOptions"])) ? $params["selectedOptions"] : NULL;

	// override selected options with what's in the request
	if (array_key_exists("name", $params)
		&& $request->hasParameter($params["name"])) {
		$selectedOptions = $request->getParameter($params["name"]);
	}

	// turn them into an array
	if ($selectedOptions!=NULL && !is_array($selectedOptions)) {
		$selectedOptions = Array($selectedOptions);
	}

	// return it
	return $selectedOptions;
}
    
function smarty_pmvc_formInput(array $params, Smarty &$smarty, $useRequestValue=TRUE) {
    if (!array_key_exists("name", $params)) {
        \pmvc\log\Log::warn("name not specified for formInput");
    }
    $request = $smarty->get_registered_object("Request");

    // add special attributes
    // type=
    if (!array_key_exists("type", $params)) {
    	$params["type"] = "text";
    }
    // id=
    if (!array_key_exists("id", $params)
    	&& array_key_exists("name", $params)) {
    	$params["id"] = $params["name"];
    }
    // value=
    if ($useRequestValue
    	&& array_key_exists("name", $params)
    	&& $request->hasParameter($params["name"])
    	&& !is_array($request->getParameter($params["name"]))) {
    	$params["value"] = $request->getParameter($params["name"]);
    }

    // render it
	return '<input'.smarty_pmvc_getAttrs($params, $smarty).' />';
}

function smarty_pmvc_formInputCheckbox(array $params, Smarty &$smarty) {
    if (!array_key_exists("value", $params)) {
        \pmvc\log\Log::warn("value not specified for formInputCheckbox");
    }
    $request = $smarty->get_registered_object("Request");

    // setup type
	$params["type"] = "checkbox";

	// get selected options
	$selectedOptions = smarty_pmvc_getSelectedOptions($params, $smarty);

	// make sure they aren't in the params
	unset($params["selectedOptions"]);

	// pre-select from selectedOptions
    if (count($selectedOptions)>0
    	&& array_key_exists("name", $params)
    	&& array_key_exists("value", $params)
    	&& array_search($params["value"], $selectedOptions)!==FALSE) {
    	$params["checked"] = "checked";
    	
    } else if (isset($params["checked"])) {
    	if (($params["checked"] === TRUE) || ($params["checked"] == "checked")) {
    		$params["checked"] = "checked";
    	} else {
    		unset($params["checked"]);
    	}
    }

    // render it
	return smarty_pmvc_formInput($params, $smarty, FALSE);
}

function smarty_pmvc_formTextArea(array $params, Smarty &$smarty) {
    if (empty($params["name"])) {
        \pmvc\log\Log::warn("name not specified for formTextArea");
    }
    $request = $smarty->get_registered_object("Request");

    // id=
    if (!array_key_exists("id", $params)
    	&& array_key_exists("name", $params)) {
    	$params["id"] = $params["name"];
    }

    // value
    $value = "";
    if (array_key_exists("value", $params)) {
    	$value = $params["value"];
    	unset($params["value"]);
    }
	if (array_key_exists("name", $params)
    	&& $request->hasParameter($params["name"])) {
    	$value = $request->getParameter($params["name"]);
    }

    // render it
    return '<textarea '.smarty_pmvc_getAttrs($params, $smarty).'>'.htmlspecialchars($value).'</textarea>';
}

function smarty_pmvc_formInputPassowrd(array $params, Smarty &$smarty) {
    $params["type"] = "password";
    $params["value"] = "";
    return smarty_pmvc_formInput($params, $smarty);
}

function smarty_pmvc_formSelect(array $params, Smarty &$smarty) {
    if (!array_key_exists("name", $params)) {
        \pmvc\log\Log::warn("name not specified for formSelect");
    }
    if (!array_key_exists("options", $params)) {
        \pmvc\log\Log::warn("options not specified for formSelect");
    } else if (!is_array($params["options"])) {
    	\pmvc\log\Log::warn("options specified for formSelect not an array");
    }

	// get selected options
	$selectedOptions = smarty_pmvc_getSelectedOptions($params, $smarty);

	// make sure they aren't in the params
	unset($params["selectedOptions"]);
	
    // id=
    if (!array_key_exists("id", $params)
    	&& array_key_exists("name", $params)) {
    	$params["id"] = $params["name"];
    }

	// get the options
    $options = $params["options"];
	if (array_key_exists("options", $params)) {
		unset($params["options"]);
	}

	// get the id for the options
	$id = "optionval_";
	if (array_key_exists("id", $params)) {
		$id = $params["id"];
	} else if (array_key_exists("name", $params)) {
		$id = $params["name"];
	}

    // build the select
    $ret = '<select '.smarty_pmvc_getAttrs($params, $smarty).'>';
    foreach ($options as $val => $text) {
    	$ret .= '<option id="'.htmlspecialchars($id.'_'.$val).'"';
    	if ($selectedOptions!=NULL && array_search($val, $selectedOptions)!==FALSE) {
    		$ret .= ' selected="selected"';
    	}
    	$ret .= ' value="'.htmlspecialchars($val).'">'.$text.'</option>';
    }
    $ret .= '</select>';

    // return the select
    return $ret;
}

function smarty_pmvc_displayFormGlobalErrors(array $params, Smarty &$smarty) {
    
	$errors = array_key_exists("errors", $params)
		? $params["errors"] 
		: $smarty->get_template_vars("formErrors");
		
    if (empty($errors) || count($errors)==0) {
        return "";
    }
	
	$start = array_key_exists("start", $params) ? $params["start"] : "<div class=\"globalErrors\">";
	$before = array_key_exists("before", $params) ? $params["before"] : "<span class=\"globalError\">";
	$after = array_key_exists("after", $params) ? $params["after"] : "</span>";
	$end = array_key_exists("end", $params) ? $params["end"] : "</div>";
	
	if (!array_key_exists("globalErrors", $errors)
		|| count($errors["globalErrors"])==0) {
        return "";
	}
	$globalErrors = $errors["globalErrors"];
	
	$ret = $start;
	foreach ($globalErrors as $error) {
		$ret .= $before.$error.$after;
	}
	$ret .= $end;
	
	return $ret;
}

function smarty_pmvc_displayFormFieldErrors(array $params, Smarty &$smarty) {
    
	$errors = array_key_exists("errors", $params)
		? $params["errors"] 
		: $smarty->get_template_vars("formErrors");
		
    if (empty($errors) || count($errors)==0) {
        return "";
    }
    
	$field = array_key_exists("field", $params) ? $params["field"] : NULL;
	$start = array_key_exists("start", $params) ? $params["start"] : "<div class=\"fieldErrors\">";
	$before = array_key_exists("before", $params) ? $params["before"] : "<span class=\"fieldError\">";
	$after = array_key_exists("after", $params) ? $params["after"] : "</span>";
	$end = array_key_exists("end", $params) ? $params["end"] : "</div>";
	
	if (!array_key_exists("fieldErrors", $errors)
		|| !array_key_exists($field, $errors["fieldErrors"])
		|| count($errors["fieldErrors"])==0) {
        return "";
	}
	$fieldErrors = $errors["fieldErrors"];
	
	if (!array_key_exists($field, $fieldErrors)
		|| count($fieldErrors[$field])==0) {
        return "";
	}
	
	$ret = $start;
	foreach ($fieldErrors[$field] as $error) {
		$ret .= $before.$error.$after;
	}
	$ret .= $end;
	
	return $ret;
}

function smarty_pmvc_getContextProperty(array $params, Smarty &$smarty) {
	
	$name    = $params['name'];
	$default = isset($params['default']) ? $params['default'] : NULL;
	
	$properties = $smarty->get_registered_object('ContextPropertiesLookup');
	if (isset($properties)) {
		return $properties->getProperty($name, $default);
	}
	return $default;
}

global $_time_formats;
$_time_formats = array(
        array(60, 'just now'),
        array(90, '1 minute'),                  // 60*1.5
        array(3600, 'minutes', 60),             // 60*60, 60
        array(5400, '1 hour'),                  // 60*60*1.5
        array(86400, 'hours', 3600),            // 60*60*24, 60*60
        array(129600, '1 day'),                 // 60*60*24*1.5
        array(604800, 'days', 86400),           // 60*60*24*7, 60*60*24
        array(907200, '1 week'),                // 60*60*24*7*1.5
        array(2628000, 'weeks', 604800),        // 60*60*24*(365/12), 60*60*24*7
        array(3942000, '1 month'),              // 60*60*24*(365/12)*1.5
        array(31536000, 'months', 2628000),     // 60*60*24*365, 60*60*24*(365/12)
        array(47304000, '1 year'),              // 60*60*24*365*1.5
        array(3153600000, 'years', 31536000),   // 60*60*24*365*100, 60*60*24*365
    );

function smarty_pmvc_niceDate(array $params, Smarty &$smarty) {
    if (empty($params["from"])) {
        \pmvc\log\Log::error("from not specified for niceDate");
    }
    
	$dateFrom = strtotime($params["from"]);
	$dateTo = array_key_exists("to", $params) ? strtotime($params["to"]) : time();

	$difference = $dateTo - $dateFrom;
	
	$message    = '';
	if ($dateFrom <= 0) {
            $message = 'a long time ago';
	} else {
		global $_time_formats;
		foreach ($_time_formats as $format) {
			if ($difference < $format[0]) {
				if (count($format) == 2) {
					$message = $format[1] . ($format[0] === 60 ? '' : ' ago');
					 break;
				} else {
					$message = ceil($difference / $format[2]) . ' ' . $format[1] . ' ago';
					break;
				}

			}
		}

	}
	
	return sprintf('<abbr title="%s">%s</abbr>',
		strftime('%a %d %b %H:%M:%S %Y', (int)$dateFrom),
		$message
	);
	
}

?>